﻿#include "MainWindow.h"
#include "ui_MainWindow.h"

#include "NoFocusDelegate.h"
#include <spdlog/sinks/stdout_sinks.h>
#include <spdlog/sinks/daily_file_sink.h>
#include <spdlog/sinks/qt_sinks.h>
#include <QDir>
#include <QDebug>
#include <QSettings>
#include <QTableWidgetItem>
#include "TrBase.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    TableUI();
    initLogger();
    qRegisterMetaType<QVector<int>>("QVector<int>");

    QSettings conf(QDir::currentPath().append("/.configs/config.ini"), QSettings::IniFormat);

    m_pManager = new CTrManager;
    m_pManager->TrAddReceiver(this);
//    m_pManager->TrUserLogin("9070", "335302", "zmin821001", "tcp://124.74.237.192:41305", "client_dytrader_1.0.0", "JH9RXJ5Z6NK3DC33");
//    m_pManager->TrSetFront("tcp://124.74.237.192:41313");
//    m_pManager->TrUserLogin("9999", "112537", "zmin821001", "tcp://180.168.146.187:10201", "simnow_client_test", "0000000000000000");
//    m_pManager->TrSetFront("tcp://180.168.146.187:10211");
//    m_pManager->TrUserLogin("9999", "112537", "zmin821001", "tcp://180.168.146.187:10130", "simnow_client_test", "0000000000000000");
//    m_pManager->TrSetFront("tcp://180.168.146.187:10131");

    bool isDebug = true;

    if(isDebug == false)
    {
        m_pManager->TrUserLogin(
                    conf.value("ctp/brokerid").toString().toStdString().c_str(),
                    conf.value("ctp/userid").toString().toStdString().c_str(),
                    conf.value("ctp/password").toString().toStdString().c_str(),
                    conf.value("ctp/tdfront").toString().toStdString().c_str(),
                    conf.value("ctp/appid").toString().toStdString().c_str(),
                    conf.value("ctp/authcode").toString().toStdString().c_str()
                    );
        m_pManager->TrSetFront(conf.value("ctp/mdfront").toString().toStdString().c_str());
    } else {
        m_pManager->TrUserLogin("9999", "112537", "zmin821001", "tcp://180.168.146.187:10130", "simnow_client_test", "0000000000000000");
        m_pManager->TrSetFront("tcp://180.168.146.187:10131");
    }

}

void MainWindow::initLogger()
{
    QSettings conf(QDir::currentPath().append("/.configs/config.ini"), QSettings::IniFormat);
    std::vector<spdlog::sink_ptr> sinks;

    sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_st>());
    QString filename = QString(".records/").append(conf.value("log/name").toString().append(".log"));
    sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_st>(filename.toStdString(), 00, 00));
    sinks.push_back(std::make_shared<spdlog::sinks::qt_color_sink_mt>(ui->textEdit, 500));

    m_Logger = std::make_shared<spdlog::logger>(conf.value("log/name").toString().toStdString(), begin(sinks), end(sinks));
    m_Logger->set_level(static_cast<level::level_enum>(conf.value("log/level").toInt()));
    m_Logger->set_pattern(conf.value("log/pattern").toString().toStdString());

    spdlog::register_logger(m_Logger);
    spdlog::flush_every(std::chrono::seconds(conf.value("log/flush").toInt()));
}

MainWindow::~MainWindow()
{
    delete ui;
}



void MainWindow::TableUI()
{
    QString headStyle   =   "QHeaderView::section {background-color:#151924; padding:5px 0px 5px 5px; color:#c8cdcd; font-size:14px; border:none; border-bottom:1px solid #be140a;}";
    //设置表头样式
    ui->tableWidget->horizontalHeader()->setStyleSheet(headStyle);
    QStringList headText;
    headText << tr("序号") << tr("合约名称") << tr("最新") << tr("现手") << tr("涨跌") << tr("涨跌幅") << tr("买价") << tr("买量") << tr("卖价") << tr("卖量") << tr("持仓量") << tr("昨收") << tr("昨结算") << tr("开盘") << tr("最高") << tr("最低") << tr("成交额(亿)") << tr("代码") << tr("最后交易日") << tr("更新");
    ui->tableWidget->setColumnCount(headText.size());
    ui->tableWidget->setHorizontalHeaderLabels(headText);
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    //ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
    //隔行变色
    //ui->tableWidget->setAlternatingRowColors(true);
    ui->tableWidget->setShowGrid(false);
    //设置垂直头不可见
    ui->tableWidget->verticalHeader()->setVisible(false);
    //设置选择行为时每次选择一行
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    //设置不可编辑
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //取消表头高亮
    ui->tableWidget->horizontalHeader()->setHighlightSections(false);
    //表头对齐
    ui->tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    ui->tableWidget->setItemDelegate(new NoFocusDelegate());
    ui->tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);


    int nWidth = 80;
    ui->tableWidget->horizontalHeader()->resizeSection(0, nWidth - 45);
    ui->tableWidget->horizontalHeader()->resizeSection(1, nWidth + 25);
    ui->tableWidget->horizontalHeader()->resizeSection(2, nWidth - 5);
    ui->tableWidget->horizontalHeader()->resizeSection(3, nWidth - 30);
    ui->tableWidget->horizontalHeader()->resizeSection(4, nWidth - 20);
    ui->tableWidget->setColumnWidth(5, nWidth - 10);
    ui->tableWidget->setColumnWidth(6, nWidth);
    ui->tableWidget->setColumnWidth(7, nWidth -25);
    ui->tableWidget->setColumnWidth(8, nWidth);
    ui->tableWidget->setColumnWidth(9, nWidth -25);

    ui->tableWidget->setColumnWidth(10, nWidth );
    ui->tableWidget->setColumnWidth(11, nWidth);
    ui->tableWidget->setColumnWidth(12, nWidth);
    ui->tableWidget->setColumnWidth(13, nWidth);
    ui->tableWidget->setColumnWidth(14, nWidth);
    ui->tableWidget->setColumnWidth(15, nWidth);
    ui->tableWidget->setColumnWidth(16, nWidth);
    ui->tableWidget->setColumnWidth(17, nWidth +30);

    ui->tableWidget->setStyleSheet("QTableWidget {background-color:#151924; color:#c8cdcd; font-size:15px; font:'宋体';}");
    ui->tabWidget->setTabText(0, "自选合约");
    ui->tabWidget->setTabText(1, "策略交易");
    ui->tabWidget->setCurrentIndex(0);
    ui->tabWidget->setTabsClosable(true);
    connect(ui->tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(slot_OnTabClose(int)));
    Load_subList();
}

void MainWindow::Load_subList()
{
    QSettings conf(QDir::currentPath().append("/.configs/config.ini"), QSettings::IniFormat);

    ui->tableWidget->clearContents();

    QStringList stfow = conf.value("user/follow").toStringList();
    for (auto i = 0; i < stfow.size(); i++) {
        QString code = stfow.at(i);
        m_mapSelection.insert(code, i);
        m_mapVolumes.insert(code, 0);

        ui->tableWidget->insertRow(i);
        ui->tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(i+1)));
        QTableWidgetItem *pName = new QTableWidgetItem(name(code));
        ui->tableWidget->setItem(i, 1, pName);
        pName->setForeground(QBrush(QColor(220,220,10)));
        ui->tableWidget->setItem(i, 3, new QTableWidgetItem(QString("--")));
    }

    connect(ui->tableWidget,SIGNAL(itemDoubleClicked(QTableWidgetItem*)),this,SLOT(slot_OnTableDoubleClicked(QTableWidgetItem*)));
}

void MainWindow::OnReceiveData(TrResponseID rId, void* wParam, void* lParam)
{
    switch (rId){
        case TrResponseID::TrOnRtnDepthMarketData:
        {
            CThostFtdcDepthMarketDataField* pData = reinterpret_cast<CThostFtdcDepthMarketDataField*>(wParam);
            update_MarketData(pData);
            emit(OnRtnDepthMarketData(pData));
            break;
        }
        case TrResponseID::TrOnQuote:
        {
            char *jData = reinterpret_cast<char*>(wParam);
            char *kStyle = reinterpret_cast<char*>(lParam);
            m_Logger->trace("QuoteData:{}, siez:{}", kStyle, QString::fromUtf8(jData).size());
            emit(OnQuote(jData,kStyle));
            break;
        }
        default:
            break;
    }
}

void MainWindow::update_MarketData(CThostFtdcDepthMarketDataField *data)
{
    if(m_mapSelection.contains(data->InstrumentID))
    {
        Contract ct = m_pManager->TrContract(data->InstrumentID);
        int row = m_mapSelection[QString(data->InstrumentID)];
        QColor fontColor = data->LastPrice > data->PreSettlementPrice ? QColor(255,50,30) : QColor(0,219,0);
        if(ui->tableWidget->item(row, 1) == nullptr || ui->tableWidget->item(row, 1)->text().isEmpty())
        {
            QTableWidgetItem *pName = new QTableWidgetItem(QString::fromLocal8Bit(ct.m_strName.c_str()));
            ui->tableWidget->setItem(row, 1, pName);
            pName->setForeground(QBrush(QColor(220,220,10)));
        }
        //
        QTableWidgetItem *pLastPrice = new QTableWidgetItem(QString::number(data->LastPrice));
        ui->tableWidget->setItem(row, 2, pLastPrice);
        pLastPrice->setForeground(QBrush(fontColor));
        //
        int nowvolume = m_mapVolumes[QString(data->InstrumentID)];
        int showVolume = nowvolume == 0 ? 0 : data->Volume-nowvolume;
        if(showVolume != 0)
        {
            QTableWidgetItem *pVolume = new QTableWidgetItem(QString::number(showVolume));
            ui->tableWidget->setItem(row, 3, pVolume);
            pVolume->setForeground(QBrush(QColor(220,220,10)));
        }
         m_mapVolumes[QString(data->InstrumentID)] = data->Volume;
        //
        QTableWidgetItem *pZhangd = new QTableWidgetItem(QString::number(data->LastPrice-data->PreSettlementPrice));
        ui->tableWidget->setItem(row, 4, pZhangd);
        pZhangd->setForeground(QBrush(fontColor));
        //
        QTableWidgetItem *pFudu = new QTableWidgetItem(QString::number((data->LastPrice-data->PreSettlementPrice)/data->PreSettlementPrice*100, 'f', 2).append("%"));
        ui->tableWidget->setItem(row, 5, pFudu);
        pFudu->setForeground(QBrush(fontColor));
        //
        QTableWidgetItem *pAskPrice = new QTableWidgetItem(QString::number(data->AskPrice1));
        ui->tableWidget->setItem(row, 6, pAskPrice);
        pAskPrice->setForeground(QBrush(fontColor));
        //
        QTableWidgetItem *pAskVolume1 = new QTableWidgetItem(QString::number(data->AskVolume1));
        ui->tableWidget->setItem(row, 7, pAskVolume1);
        pAskVolume1->setForeground(QBrush(QColor(220,220,10)));
        //
        QTableWidgetItem *pBidPrice1 = new QTableWidgetItem(QString::number(data->BidPrice1));
        ui->tableWidget->setItem(row, 8, pBidPrice1);
        pBidPrice1->setForeground(QBrush(fontColor));
        //
        QTableWidgetItem *pBidVolume1 = new QTableWidgetItem(QString::number(data->BidVolume1));
        ui->tableWidget->setItem(row, 9, pBidVolume1);
        pBidVolume1->setForeground(QBrush(QColor(220,220,10)));
        //
        QTableWidgetItem *pOpenInterest = new QTableWidgetItem(QString::number(data->OpenInterest));
        ui->tableWidget->setItem(row, 10, pOpenInterest);
        pOpenInterest->setForeground(QBrush(QColor(220,220,10)));
        //
        QTableWidgetItem *pPreClosePrice = new QTableWidgetItem(QString::number(data->PreClosePrice));
        ui->tableWidget->setItem(row, 11, pPreClosePrice);
        pPreClosePrice->setForeground(QBrush(QColor(231,231,231)));
        //
        QTableWidgetItem *pPreSettlementPrice = new QTableWidgetItem(QString::number(data->PreSettlementPrice));
        ui->tableWidget->setItem(row, 12, pPreSettlementPrice);
        pPreSettlementPrice->setForeground(QBrush(QColor(231,231,231)));
        //
        QTableWidgetItem *pOpenPrice = new QTableWidgetItem(QString::number(data->OpenPrice));
        ui->tableWidget->setItem(row, 13, pOpenPrice);
        pOpenPrice->setForeground(QBrush(fontColor));
        //
        QTableWidgetItem *pHighestPrice = new QTableWidgetItem(QString::number(data->HighestPrice));
        ui->tableWidget->setItem(row, 14, pHighestPrice);
        pHighestPrice->setForeground(QBrush(fontColor));
        //
        QTableWidgetItem *pLowestPrice = new QTableWidgetItem(QString::number(data->LowestPrice));
        ui->tableWidget->setItem(row, 15, pLowestPrice);
        pLowestPrice->setForeground(QBrush(fontColor));
        //
        QTableWidgetItem *pTurnover = new QTableWidgetItem(QString::number(data->Turnover/100000000, 'f', 2));
        ui->tableWidget->setItem(row, 16, pTurnover);
        pTurnover->setForeground(QBrush(QColor(231,231,231)));
        //
        QTableWidgetItem *pExCode = new QTableWidgetItem(QString(ct.m_strExchg.c_str()).append(".").append(data->InstrumentID));
        ui->tableWidget->setItem(row, 17, pExCode);
        pExCode->setForeground(QBrush(QColor(220,220,10)));
        //
        QTableWidgetItem *pExpireDate = new QTableWidgetItem(QString::number(ct.m_uExpireDate));
        ui->tableWidget->setItem(row, 18, pExpireDate);
        pExpireDate->setForeground(QBrush(QColor(220,220,10)));
        //
        QTableWidgetItem *pUpdateTime = new QTableWidgetItem(QString(data->UpdateTime).append(".").append(QString::number(data->UpdateMillisec)));
        ui->tableWidget->setItem(row, 19, pUpdateTime);
        pUpdateTime->setForeground(QBrush(QColor(231,231,231)));
    }
}

QString MainWindow::name(const QString& code)
{

    Contract ct = m_pManager->TrContract(code.toStdString().c_str());

    return QString::fromLocal8Bit(ct.m_strName.c_str());
}

void MainWindow::slot_OnTableDoubleClicked(QTableWidgetItem* item)
{
    QString code = nullptr;
    for (auto itor = m_mapSelection.begin(); itor != m_mapSelection.end(); ++itor)
    {
        if(itor.value() == item->row())
        {
            code = itor.key();
            break;
        }
    }
    if(code != nullptr)
    {
        if(!m_vecTabWidget.contains(code))
        {
            m_vecTabWidget.push_back(code);
            TrKlineWidget   *pWidget = new TrKlineWidget(m_pManager, code, KP_Minute60);
            m_mapTrKlineWidgets.insert(code, pWidget);
            ui->tabWidget->addTab(pWidget, name(code));
            ui->tabWidget->setCurrentWidget(pWidget);
            connect(this, SIGNAL(OnRtnDepthMarketData(CThostFtdcDepthMarketDataField*)), pWidget->data, SLOT(OnTick(CThostFtdcDepthMarketDataField*)));
            connect(this, SIGNAL(OnQuote(char*,char*)), pWidget->data, SLOT(OnQuote(char*,char*)));
            m_pManager->TrQuote(code.toStdString().c_str(), KP_Minute60);
        }
    }

}

void MainWindow::slot_OnTabClose(int index)
{
    if(index <= 1) return;
    QString code = nullptr;
    QWidget *cloWidget = ui->tabWidget->widget(index);
    for (auto itor = m_mapTrKlineWidgets.begin(); itor != m_mapTrKlineWidgets.end(); ++itor)
    {
        if(itor.value() == cloWidget)
        {
            code = itor.key();
            break;
        }
    }
    m_mapTrKlineWidgets.erase(m_mapTrKlineWidgets.find(code));
    m_vecTabWidget.removeOne(code);
    ui->tabWidget->removeTab(index);
    if(cloWidget)
        delete cloWidget;

}

